/**************************************************************************************
*
*	Copyright (C) 2010 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	GraphicsTypes.h
*
*	Description -	Graphics/Renderer data types. 
*
*	Comments	-
*
*	Modification History:
*			Name			   Date					Description
*			CodeSushi	-	10/16/2010	-	Creation of this file
**************************************************************************************/

#ifndef _PSX_GRAPHICS_TYPES_H_
#define _PSX_GRAPHICS_TYPES_H_

#include "PulseSTD.h"
#include "Vector3.h"
#include "Color.h"
#include "String.h"

namespace Pulse
{
	PSX_EnumBegin( ERendererType )
		UNKNOWN,
		DX9,
	PSX_EnumEnd()

	PSX_EnumBegin( EProcessingType )
		UNKNOWN,
		SOFTWARE,
		MIXED,
		HARDWARE,
		PURE_HARDWARE,
	PSX_EnumEnd()

	PSX_EnumBegin( ETextureAddressingMode )
		WRAP,
		BORDER,
		CLAMP,
		MIRROR,
	PSX_EnumEnd()

	PSX_EnumBegin( ETextureFilter )
		UNKNOWN,
		NONE,
		POINT,			// Point filtering
		BILINEAR,		// Bilinear filtering
		ANISOTROPIC,	// Anisotropic filtering
	PSX_EnumEnd()

	PSX_EnumBegin( EBlendType )
		__UNUSED__,
		ZERO,		// 1
		ONE,
		SRCCOLOR,
		INVSRCCOLOR,
		SRCALPHA,
		INVSRCALPHA,
		DESTALPHA,
		INVDESTALPHA,
		DESTCOLOR,
		INVDESTCOLOR,
		SRCALPHASAT,
		BOTHSRCALPHA,
		BOTHINVSRCALPHA,
		BLENDFACTOR,
		INVBLENDFACTOR,
	PSX_EnumEnd()

	PSX_EnumBegin( EBlendOp )
		__UNUSED__,
		ADD,		// 1
		SUBTRACT,
		REVSUBTRACT,
		MIN,
		MAX,
	PSX_EnumEnd()

	PSX_EnumBegin( EFillMode )
		UNKNOWN		= (1<<0),
		DOT			= (1<<1),
		WIREFRAME	= (1<<2),
		SOLID		= (1<<3),
		TEXTURED	= (1<<4),
	PSX_EnumEnd()

	PSX_EnumBegin( ECullMode )
		NONE,
		CW,		// clockwise
		CCW,	// counter-clockwise
	PSX_EnumEnd()

	PSX_EnumBegin( ERenderMode )
		_2D,
		_3D,
	PSX_EnumEnd()


	struct RenderState
	{
		UINT				globalStates;
		FLOAT				zBias;
		FLOAT				gamma;
		BOOL				blight;
		BOOL				bAlphaBlend;
		BOOL				bSeparateAlphaBlend;
		BOOL				bZWrite;
		BOOL				bZBuffer;
		BOOL				bAlphaTest;
		BOOL				bScissorTest;
		DWORD				alphaTestRef;
		EBlendType::Type	blendSource;
		EBlendType::Type	blendDest;
		EBlendType::Type	alphaBlendSource;
		EBlendType::Type	alphaBlendDest;
		EBlendOp::Type		blendOp;
		ECullMode::Type		cullMode;
		EFillMode::Type		fillMode;
		Color				ambient;				// ambient light color
		
		RenderState( void )
			: globalStates( 0 ), zBias( 0.0f ), gamma( 1.0f ), blight( TRUE ), bAlphaBlend( FALSE ),
			bSeparateAlphaBlend( FALSE ), bZWrite( TRUE ), bZBuffer( TRUE ), bAlphaTest( FALSE ), 
			bScissorTest( FALSE ), alphaTestRef( 1 ), blendSource( EBlendType::ONE ), blendDest( EBlendType::ZERO ),
			alphaBlendSource( EBlendType::ONE ), alphaBlendDest( EBlendType::ZERO ), blendOp( EBlendOp::ADD ),
			cullMode( ECullMode::CW ), fillMode( EFillMode::SOLID ), ambient( Color::BLACK )
		{
		}
	};

	struct DisplayMode
	{
		UINT 					adapter;
		UINT 					width;
		UINT 					height;
		BOOL 					bWindowed;
		BOOL 					bVSync;
		EProcessingType::Type	processingType;

		RenderState				renderState;

		ERenderMode::Type		renderMode;

		// Texture filtering settings
		ETextureFilter::Type filterMin[8];
		ETextureFilter::Type filterMag[8];
		ETextureFilter::Type filterMip[8];

		ETextureAddressingMode::Type textureAddressingMode[8];


		DisplayMode( void )
			: adapter( 0 ), width( 800 ), height( 600 ), bWindowed( TRUE ), bVSync( FALSE ),
			processingType( EProcessingType::PURE_HARDWARE )
		{
			for ( SIZE_T i = 0; i < 8; ++i )
			{
				filterMin[i] = filterMag[i] = filterMin[i] = ETextureFilter::BILINEAR;
				textureAddressingMode[i] = ETextureAddressingMode::CLAMP;
			}
		}
	};

	PSX_EnumBegin( EGraphicsCaps )
		MAX_ANISOTROPY,			// Maximum anisotropy for anisotropic texture filtering
		MIN_ANISOTROPY,			// Anisotropy for minifying textures is supported
		MAG_ANISOTROPY,			// Anisotropy for magnifying textures is supported
		MAX_CLIPPLANES,			// How many clipping planes could be defined and used
		MAX_INDICES_COUNT,		// How many vertex indices can be used in a buffer
		MAX_PRIMITIVE_COUNT,	//  How many primitives can be used in one draw call
		MAX_LIGHTS,				// Maximum number of active lights being active at the same time
		MAX_RTS,				// How many simultanous render targets can be used
		MAX_TEXTURE_HEIGHT,		// Maximum texture height
		MAX_TEXTURE_WIDTH,		// Maximum texture width
		VERTEX_SHADER,			// What version of vertex shaders is supported
		GEOMETRY_SHADER,		// What version of geometry shaders is supported
		PIXEL_SHADER,			// What version of pixel shaders is supported
	PSX_EnumEnd()

	PSX_EnumBegin( ETextureFormat )
		UNKNOWN,
		DEFAULT,					// Default format (taken from file or unknown)
		A8R8G8B8,					// Default - 32 bit. 8 bits per channel
		A2R10G10B10,				// 32 bit, 2 bit alpha and 10 bit RGB channels
		R8G8B8,						// 32 bit without alpha - alpha channel inaccessible
		A1R5G5B5,					// 16 bit - 1 per alpha and 5 per other channels
		R5G5B5,						// 16 bit - 5 per colour channels. No alpha
		R5G6B5,						// 16 bit - 5 bits per red and blue and 6 per green
		G16R16F,					// 32 bit floating point. Only red and green channels
		A16B16G16R16F,				// 64 bit, 4 channel floating point texture
		R16F,						// 16 bit, 1 channel floating point texture
		G32R32F,					// 64 bit, 2 channel floating point texture
		R32F,						// 32 bit, 1 channel floating point texture
		A32B32G32R32F,				// 128 bit, 4 channel floating point texture
		A8,							// 8 bit, 1-channel texture
	PSX_EnumEnd()

	PSX_EnumBegin( ETextureType )
		UNKNOWN,
		_1D,			// 1D texture
		_2D,			// 2D texture - 
		_3D,			// 3D texture - expensive memory usage
		_CUBE,		// Cube texture - 6 sides
	PSX_EnumEnd()

	PSX_EnumBegin( ETextureUsage )
		UNKNOWN,
		NORMAL,			// Regular texture
		RENDERTARGET,	// Texture used to render scene
		DYNAMIC,		// We can write into it
	PSX_EnumEnd()

	struct ETextureFilterType
	{
		enum Type
		{
			MIN = (1<<0),	// Minification filter
			MAG = (1<<1),	// Magnification filter
			MIP = (1<<2),	// Mip-mapping filter
			EnumCount = 3,
		};
	};

	PSX_EnumBegin( EClearBufferType )
		UNKNOWN			= (1 << 0),
		DEPTH			= (1 << 1),
		STENCIL			= (1 << 2),
		RENDER_TARGET	= (1 << 3),
	PSX_EnumEnd()

	PSX_EnumBegin( EPrimitiveType )
		UNKNOWN			= 0,
		POINT			= 1,
		LINE_LIST		= 2,
		LINE_STRIP		= 3,
		TRIANGLE_LIST	= 4,
		TRIANGLE_STRIP	= 5,
		TRIANGLE_FAN	= 6,
	PSX_EnumEnd()

	PSX_EnumBegin( EVertexBufferType )
		UNKNOWN,
		STATIC,
		DYNAMIC,
	PSX_EnumEnd()

	PSX_EnumBegin( EVertexElementUsage )
		POSITION,
		NORMAL,
		BINORMAL,
		TANGENT,
		TEXCOORD,
		COLOR,
		FOG,
		DEPTH,
		SAMPLE,
		BLEND_WEIGHTS,
		BLEND_INDICES,
	PSX_EnumEnd()

	struct VertexElement
	{
		UINT						stream;		// The stream index the vertex component is associated.
		UINT						offset;		// The offset in butes from the start of the vertex structure.
		EVertexElementUsage::Type	usage;		// What the element will be used for.
		UINT						usageIndex;	// [0, 15] Used to indentify multiple vertex components of the same usage. 
	};

	struct Vertex1P1D
	{
		Vector3 position;
		DWORD	diffuse;
	};

	// Vertex for 2D rendering
	struct Vertex2D
	{
		Vector3 position;
		DWORD	color;
		Vector2 texCoord;
	};

	// Shader stuff
	///////////////

	PSX_EnumBegin( EShaderType )
		UNKNOWN,
		VERTEX,
		GEOMETRY,
		PIXEL,
		EFFECT,		// An effect is composed of all shader types
	PSX_EnumEnd()

	struct ShaderConstantSemantic
	{
		typedef void (*SemanticFunction)( void *, SIZE_T );

		String				name;			// Semantic name
		String				dataType;		// Data type associated with
		SemanticFunction	semanticFunc;	// Function called for semantic

		ShaderConstantSemantic( void ) : semanticFunc( NULL )
		{

		}
	};

	PSX_EnumBegin( EShaderConstantType )
		FLOAT,	// 32-bit floating point value
		INT,	// 32-bit signed integer
		BOOL,	// true or false
		//UINT,	// 32-bit unsigned integer
		//DOUBLE,	// 64-bit floating point vlaue.
	PSX_EnumEnd()

	struct ShaderConstantType
	{
		String				name;
		SIZE_T				dataCount;
		EShaderConstantType type;
	};

	PSX_EnumBegin( EDrawOrder )
		PRE,
		SCENE,
		POST,
	PSX_EnumEnd()

}

#endif /* _PSX_GRAPHICS_TYPES_H_ */